import { BaseModule } from '../../../lib/abstract'
import { ToolKit } from '../../../lib/utils/toolkit'
import { PreventionStrategy } from '../../../lib/utils/ui/event'
import { logger } from '../../../types/constants'
import { ConfigManager } from '../../config_manager'

interface Config {
  enabled?: boolean
  cleanClipboard?: boolean // 是否清理剪贴板中的附加信息
  customCleaner?: (text: string) => string // 自定义清理函数
}

/**
 * 版权信息清理模块
 */
export class CopyCopyright extends BaseModule {
  readonly id: string = 'copy_copyright'
  readonly name: string = 'CopyCopyright'
  readonly isInitialized: boolean = false
  readonly supportedPlatforms: string[] = ConfigManager.getInstance().moduleSupportedPlatforms(this.name)
  private static instance: CopyCopyright

  config: Config = {
    enabled: true,
    cleanClipboard: true,
  }

  private handler?: (e: ClipboardEvent) => void

  /**
   * 获取单例实例
   */
  public static getInstance(): CopyCopyright {
    if (!CopyCopyright.instance) {
      CopyCopyright.instance = new CopyCopyright()
    }
    return CopyCopyright.instance
  }

  /**
   * 销毁模块
   */
  destroy(): void {
    if (this.handler) {
      document.removeEventListener('copy', this.handler, true)
    }
    super.destroy()
  }

  /**
   * 执行模块核心逻辑
   */
  async core(): Promise<void> {
    this.loadConfig()

    if (!this.config.enabled) {
      this.destroy()
      return
    }

    await this.setupCopyProtection()
  }

  async onToggleCallback(_id: string, checked: boolean): Promise<void> {
    checked ? await this.core() : this.destroy()
  }

  /**
   * 执行模块核心逻辑
   */
  private async setupCopyProtection() {
    this.handler = async (e: ClipboardEvent) => {
      ToolKit.ui.event.preventEvent(e, PreventionStrategy.PreventOnly)
      ToolKit.ui.event.stopImmediatePropagation(e)

      let selectedText = ToolKit.browser.selection.getSelectedText()

      if (!selectedText)
        return

      // 某些浏览器会限制剪贴板相关操作的日志输出，出于安全考虑，直接使用 console 打印日志不会在控制台显示
      logger.info('原始剪贴板内容如下：', selectedText)

      if (this.config.cleanClipboard || this.config.customCleaner) {
        // 使用自定义清理函数或默认清理
        if (this.config.customCleaner) {
          selectedText = this.config.customCleaner(selectedText)
        }
        else if (this.config.cleanClipboard) {
          // 移除常见的版权信息
          selectedText = selectedText
            .replace(/\s*著作权归作者所有。.*?\n*/g, '')
            .replace(/\s*版权声明：.*?\n*/g, '')
            .replace(/\s*转载请注明来源。.*?\n*/g, '')
        }
      }

      await ToolKit.ui.clipboard.copyToClipboard(selectedText.trim())
    }

    // copy 是全局事件，只能在 document 上监听
    document.addEventListener('copy', this.handler, true)
  }

  /**
   * 应用新配置并更新模块
   */
  applyConfig(config: Partial<Config>): void {
    super.updateConfig(config)
    // 重新执行
    this.setupCopyProtection().catch(console.error)
    logger.info(`[${this.name}] Config updated and apply`, this.config)
  }

  /**
   * 重置模块
   */
  async refreshModule(): Promise<void> {
    try {
      this.destroy()
      await this.core()
      logger.info(`[${this.name}] Module refreshed`)
    }
    catch (err: any) {
      logger.error(`[${this.name}] Module refresh failed`, err)
    }
  }
}
